package wsi.gui.resolve.model;

import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

import org.rygh.core.util.UIo;

import wsi.exp.Exp2TreeToEntity;
import wsi.exp.exp5.JudgeFile;
import wsi.exp.exp5.JudgeFileManager;
import wsi.function.Function;
import wsi.function.FunctionController;

public class FunctionStatTuple {

	private final StringProperty functionName = new SimpleStringProperty(this,
			"functionName");
	private final IntegerProperty numberOfFiles = new SimpleIntegerProperty(
			this, "numberOfFiles");
	private final IntegerProperty numberOfPairs = new SimpleIntegerProperty(
			this, "numberOfPairs");
	private final IntegerProperty numberOfJudgedPairs = new SimpleIntegerProperty(
			this, "numberOfJudgedPairs");
	private final BooleanProperty completed = new SimpleBooleanProperty(this,
			"completed");
	private final DoubleProperty precision = new SimpleDoubleProperty(this,
			"precision");

	private boolean valid = false;
	private final Function function;

	public FunctionStatTuple(String service, File functionDir) {
		String func_name = functionDir.getName();

		function = FunctionController.shared().getFunction(service, func_name);
		valid = Exp2TreeToEntity.isFunctionCorrectlyDetected(function);

		if (!valid)
			return;

		load(functionDir);
	}

	public BooleanProperty completedProperty() {
		return completed;
	}

	public StringProperty functionNameProperty() {
		return functionName;
	}

	public Function getFunction() {
		return function;
	}

	public int getNumberOfFiles() {
		return numberOfFiles.get();
	}

	public int getNumberOfJudgedPairs() {
		return numberOfJudgedPairs.get();
	}

	public int getNumberOfPairs() {
		return numberOfPairs.get();
	}

	public boolean isCompleted() {
		return completed.get();
	}

	public boolean isValid() {
		return valid;
	}

	private void load(File functionDir) {
		String func_name = functionDir.getName();

		functionName.set(func_name);

		JudgeFileManager jm = new JudgeFileManager(function);

		File[] files = jm.getXmlFiles();
		numberOfFiles.set(files.length);

		int c = 0, p = 0, j = 0;

		Pattern pat = Pattern.compile("<t:matched_entity");

		for (File f : files) {
			Matcher m = pat.matcher(UIo.readFile(f));

			while (m.find())
				p++;
		}

		numberOfPairs.set(p);

		files = jm.getJudgedFiles();

		JudgeFile judgefile;

		for (File f : files) {
			judgefile = new JudgeFile(f);

			c += judgefile.getCorrectSize();
			j += judgefile.getJudgedSize();
		}

		numberOfJudgedPairs.set(j);
		completed.set(j == p);

		precision.set(p > 0 ? 100. * c / p : Double.NaN);

	}

	public IntegerProperty numberOfFilesProperty() {
		return numberOfFiles;
	}

	public IntegerProperty numberOfJudgedFilesProperty() {
		return numberOfJudgedPairs;
	}

	public IntegerProperty numberOfPairsProperty() {
		return numberOfPairs;
	}

	public DoubleProperty precisionProperty() {
		return precision;
	}

}
